#pragma once

#include "NetworkPackets.h"

namespace Putin{

	class NetworkConnection;

	/*!
	 * \brief
	 * Describes a function taking a NetworkConnection and a NetworkPacket
	 *
	 */
	class NetFunctorB
	{
	public:
		virtual ~NetFunctorB(){}
		virtual void operator()(NetworkConnection* conn, NetworkPacket* np)=0;
	};

	/*!
	 * \brief
	 * A type specific implementation of a member function pointer wrapper
	 * 
	 * \param T
	 * The class type that owns the member function pointer wrapped
	 * 
	 * The object simply passes a NetworkConnection and a NetworkPacket 
	 * on to a specific member function in some other object specified.
	 * 
	 * \remarks
	 * Write remarks for NetFunctor here.
	 * 
	 * \see
	 * Separate items with the '|' character.
	 */
	template <typename T>
	class NetFunctor : public NetFunctorB
	{
	public:
		typedef void(T::*Function)(NetworkConnection* conn, NetworkPacket* np);

		/*!
		 * \brief Creates a functor
		 * 
		 * \param f the function to pass on
		 * 
		 * \param o a pointer to the owner object
		 * 
		 * Usage:
		 *  new NetFunctor<MyClass>(&MyClass::handlePacket,this)
		 */
		NetFunctor(Function f, T* o)
		{
			mFunction = f;
			mObject = o;
		}

		virtual ~NetFunctor(){}

		void operator()(NetworkConnection* conn, NetworkPacket* np)
		{
			return (mObject->*mFunction)(conn,np);
		}

	private:
		T* mObject;
		Function mFunction;
	};



	/*!
	 * \brief
	 * Wrapping some basic transmission functions for a network connection
	 * 
	 * This wrapps basic functionallity for sending messages over the network
	 * The implementation is done in a OpenTNL EventConnection extended to
	 * RtsConnection, but that whole big class wont be needed in most cases.
	 * so this little base class will do just fine!
	 * 
	 * \see
	 * RtsConnection
	 */
	class NetworkConnection
	{
	public:
		/*!
		 * \brief
		 * Send a message to all clients from the server
		 * 
		 * \param np The NetworkPacket to send
		 *
		 * \param skipEcho Do not send back to the connection it came from
		 * 
		 * Send a message to all clients from the server
		 */
		virtual void broadcast(NetworkPacket* np, bool skipEcho=true)= 0;
		/*!
		 * \brief
		 * Send a message from the server to the client. prob. Used to reply on something
		 * 
		 * \param np The NetworkPacket to send
		 * 
		 * Send a message to all clients from the server
		 */

		virtual void send2Client(NetworkPacket* np)= 0;
		
		/*!
		 * \brief
		 * Send a message from the client to the server
		 * 
		 * \param np The NetworkPacket to send
		 * 
		 * Send a message to all clients from the server
		 */
		virtual void send2Server(NetworkPacket* np) = 0;


		/*!
		 * \brief Add a callback handler for incomming packet events
		 * 
		 * \param nf the NetFunctor handler
		 * \see
		 * NetFunctor 
		 */
		virtual void addHandler(NetFunctorB* nf) = 0;
		virtual void addOnConnectHandler( NetFunctorB* nf) = 0;
		virtual void addOnDisconnectedHandler(NetFunctorB* nf) = 0;


		// Some trivial things
		virtual std::string getRemoteAddress() = 0;

	};
}